home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / comms / term / extras / hydracom / hydracom-source.lha / misc.c < prev    next >
C/C++ Source or Header  |  1995-12-15  |  19KB  |  722 lines

  1. /*=============================================================================
  2.  
  3.                               HydraCom Version 1.00
  4.  
  5.                          A sample implementation of the
  6.                    HYDRA Bi-Directional File Transfer Protocol
  7.  
  8.                              HydraCom was written by
  9.                    Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT
  10.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  11.  
  12.                        The HYDRA protocol was designed by
  13.                  Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT and
  14.                              Joaquim H. Homrighausen
  15.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  16.  
  17.  
  18.   Revision history:
  19.   06 Sep 1991 - (AGL) First tryout
  20.   .. ... .... - Internal development
  21.   11 Jan 1993 - HydraCom version 1.00, Hydra revision 001 (01 Dec 1992)
  22.  
  23.  
  24.   For complete details of the Hydra and HydraCom licensing restrictions,
  25.   please refer to the license agreements which are published in their entirety
  26.   in HYDRACOM.C and LICENSE.DOC, and also contained in the documentation file
  27.   HYDRACOM.DOC
  28.  
  29.   Use of this file is subject to the restrictions contained in the Hydra and
  30.   HydraCom licensing agreements. If you do not find the text of this agreement
  31.   in any of the aforementioned files, or if you do not have these files, you
  32.   should immediately contact LENTZ SOFTWARE-DEVELOPMENT and/or Joaquim
  33.   Homrighausen at one of the addresses listed below. In no event should you
  34.   proceed to use this file without having accepted the terms of the Hydra and
  35.   HydraCom licensing agreements, or such other agreement as you are able to
  36.   reach with LENTZ SOFTWARE-DEVELOMENT and Joaquim Homrighausen.
  37.  
  38.  
  39.   Hydra protocol design and HydraCom driver:         Hydra protocol design:
  40.   Arjen G. Lentz                                     Joaquim H. Homrighausen
  41.   LENTZ SOFTWARE-DEVELOPMENT                         389, route d'Arlon
  42.   Langegracht 7B                                     L-8011 Strassen
  43.   3811 BT  Amersfoort                                Luxembourg
  44.   The Netherlands
  45.   FidoNet 2:283/512, AINEX-BBS +31-33-633916         FidoNet 2:270/17
  46.   arjen_lentz@f512.n283.z2.fidonet.org               joho@ae.lu
  47.  
  48.   Please feel free to contact us at any time to share your comments about our
  49.   software and/or licensing policies.
  50.  
  51. =============================================================================*/
  52.  
  53. #include "hydracom.h"
  54.  
  55. #ifdef AMIGA
  56. #include <dos/dosextens.h>
  57. #include <clib/dos_protos.h>
  58. #endif    /* AMIGA */
  59.  
  60. static char *chatstart = "\007\007 * Chat mode start\r\n";
  61. static char *chatend   = "\007\007\r\n * Chat mode end\r\n";
  62. static char *chattime  = "\007\007\r\n * Chat mode end - timeout\r\n";
  63.  
  64.  
  65. static void loc_puts (char *s)
  66. {
  67. #ifdef AMIGA
  68.     ConPrintf(LocalRequest,s);
  69. #else
  70.         while (*s) {
  71.               if (*s == '\007')
  72. #if WIN_AGL
  73.                  (void) win_bell();
  74. #else
  75.                  putc(7,stderr);
  76. #endif
  77.               else
  78. #if WIN_AGL
  79.                  win_putc(local_win,*s);
  80. #else
  81.                  putch(*s);
  82. #endif
  83.               s++;
  84.         }
  85. #endif    /* AMIGA */
  86. }/*loc_puts()*/
  87.  
  88.  
  89. int keyabort (void)
  90. {
  91. #define CHATLEN 256
  92.         static byte     chatbuf1[CHATLEN + 5],
  93.                         chatbuf2[CHATLEN + 5],
  94.                        *curbuf = chatbuf1;
  95.         static boolean  warned = false;
  96.         boolean         esc = false;
  97.         char           *p;
  98.         word            c;
  99.  
  100.         if (chattimer > 0L) {
  101.            if (time(NULL) > chattimer) {
  102.               chattimer = lasttimer = 0L;
  103.               hydra_devsend("CON",(byte *) chattime,strlen(chattime));
  104.               loc_puts(&chattime[2]);
  105.            }
  106.            else if ((time(NULL) + 10L) > chattimer && !warned) {
  107.               loc_puts("\007\r\n * Warning: chat mode timeout in 10 seconds\r\n");
  108.               warned = true;
  109.            }
  110.         }
  111.         else if (chattimer != lasttimer) {
  112.            if (chattimer ==  0L) {
  113.               if (nobell) p = " * Remote has chat facility with bell disabled\n";
  114.               else        p = " * Remote has chat facility with bell enabled\n";
  115.               hydra_devsend("CON",(byte *) p,(int) strlen(p));
  116.               loc_puts(" * Hydra session in progress, chat facility now available\r\n");
  117.            }
  118.            else if (chattimer == -1L)
  119.               loc_puts(" * Hydra session in init state, can't chat yet\r\n");
  120.            else if (chattimer == -2L)
  121.               loc_puts(" * Remote has no chat facility available\r\n");
  122.            else if (chattimer == -3L) {
  123.               if (lasttimer > 0L) loc_puts("\r\n");
  124.               loc_puts(" * Hydra session in exit state, can't chat anymore\r\n");
  125.            }
  126.            lasttimer = chattimer;
  127.         }
  128.  
  129. #if WIN_AGL
  130.         while (win_keyscan()) {
  131. #else
  132. #ifdef AMIGA
  133.         while (ConScanKey()) {
  134. #else
  135.         while (kbhit()) {
  136. #endif
  137. #endif
  138.               switch (c = get_key()) {
  139.                      case Esc:
  140.                           esc = true;
  141.                           break;
  142.  
  143.                      case Alt_C:
  144.                           if (chattimer == 0L) {
  145.                              hydra_devsend("CON",(byte *) chatstart,strlen(chatstart));
  146.                              loc_puts(&chatstart[2]);
  147.                              chattimer = lasttimer = time(NULL) + CHAT_TIMEOUT;
  148.                           }
  149.                           else if (chattimer > 0L) {
  150.                              chattimer = lasttimer = 0L;
  151.                              hydra_devsend("CON",(byte *) chatend,strlen(chatend));
  152.                              loc_puts(&chatend[2]);
  153.                           }
  154.                           else
  155.                              loc_puts("\007");
  156.                           break;
  157.  
  158.                      default:
  159.                           if (c < ' ' || c > 126)
  160.                              break;
  161.  
  162.                      case '\r':
  163.                      case '\a':
  164.                      case '\b':
  165.                           if (chattimer <= 0L)
  166.                              break;
  167.  
  168.                           chattimer = time(NULL) + CHAT_TIMEOUT;
  169.                           warned = false;
  170.  
  171.                           if (chatfill >= CHATLEN)
  172.                              loc_puts("\007");
  173.                           else {
  174.                              switch (c) {
  175.                                     case '\r':
  176.                                          curbuf[chatfill++] = '\n';
  177.                                          loc_puts("\r\n");
  178.                                          break;
  179.  
  180.                                     case '\b':
  181.                                          if (chatfill > 0 && curbuf[chatfill - 1] != '\n')
  182.                                             chatfill--;
  183.                                          else {
  184.                                             curbuf[chatfill++] = '\b';
  185.                                             curbuf[chatfill++] = ' ';
  186.                                             curbuf[chatfill++] = '\b';
  187.                                          }
  188.                                          loc_puts("\b \b");
  189.                                          break;
  190.  
  191.                                     default:
  192.                                          curbuf[chatfill++] = (byte) c;
  193.                                          if (c != 7)
  194. #if WIN_AGL
  195.                                             win_putc(local_win,c);
  196. #else
  197. #ifdef AMIGA
  198.                                             ConPrintf(LocalRequest,"%lc",c);
  199. #else
  200.                                             putch(c);
  201. #endif
  202. #endif
  203.                                          break;
  204.                              }
  205.                           }
  206.                           break;
  207.               }
  208.  
  209. #ifdef AMIGA
  210.            if (chatfill >= CHATLEN - 3 && hydra_devsend("CON",curbuf,chatfill)) {
  211.               curbuf = (curbuf == chatbuf1) ? chatbuf2 : chatbuf2;
  212.               chatfill = 0;
  213.            }
  214. #endif
  215.         }
  216.  
  217.         if (chatfill > 0 && hydra_devsend("CON",curbuf,chatfill)) {
  218.            curbuf = (curbuf == chatbuf1) ? chatbuf2 : chatbuf2;
  219.            chatfill = 0;
  220.         }
  221.  
  222.         return (esc);
  223. }/*keyabort()*/
  224.  
  225.  
  226. void rem_chat (byte *data, word len)
  227. {
  228. #if !WIN_AGL && !defined(AMIGA)
  229.         local_x = wherex();
  230.         local_y = wherey();
  231.         window(1,11,80,17);
  232.         gotoxy(remote_x,remote_y);
  233. #endif
  234.  
  235.         while (*data) {
  236.               switch (*data) {
  237.                      case '\a':
  238.                           if (!nobell) {
  239. #if WIN_AGL
  240.                              (void) win_bell();
  241. #else
  242. #ifdef AMIGA
  243.                              ConPrintf(RemoteRequest,"\a");
  244. #else
  245.                              putc(7,stderr);
  246. #endif
  247. #endif
  248.                           }
  249.                           break;
  250.  
  251.                      case '\n':
  252. #if WIN_AGL
  253.                           win_putc(remote_win,'\r');
  254. #else
  255. #ifdef AMIGA
  256.                           ConPrintf(RemoteRequest,"\r");
  257. #else
  258.                           putch('\r');
  259. #endif
  260. #endif
  261.                           /* fallthrough to default */
  262.  
  263.                      default:
  264. #if WIN_AGL
  265.                           win_putc(remote_win,(int) *data);
  266. #else
  267. #ifdef AMIGA
  268.                           ConPrintf(RemoteRequest,"%lc",*data);
  269. #else
  270.                           putch((int) *data);
  271. #endif
  272. #endif
  273.                           break;
  274.               }
  275.               data++;
  276.         }
  277.  
  278. #if !WIN_AGL && !defined(AMIGA)
  279.         remote_x = wherex();
  280.         remote_y = wherey();
  281.         window(1,19,80,25);
  282.         gotoxy(local_x,local_y);
  283. #endif
  284. }/*rem_chat()*/
  285.  
  286.  
  287. int parse(char *string)
  288. {
  289. #ifdef AMIGA
  290.         int ac = 0;
  291.         int i,from = 0,inQuote = 0,len = strlen(string);
  292.  
  293.     for(i = 0 ; i < len ; i++)
  294.     {
  295.         switch(string[i])
  296.         {
  297.             case '\"':
  298.  
  299.                 if(inQuote)
  300.                 {
  301.                     string[i] = 0;
  302.  
  303.                     av[ac++] = &string[from];
  304.  
  305.                     inQuote = 0;
  306.                 }
  307.                 else
  308.                     inQuote = TRUE;
  309.  
  310.                 from = i + 1;
  311.  
  312.                 break;
  313.  
  314.             case ' ':
  315.  
  316.                 if(inQuote)
  317.                     break;
  318.  
  319.             case '\t':
  320.             case '\r':
  321.             case '\n':
  322.             case '\032':
  323.  
  324.                 if(i != from)
  325.                 {
  326.                     string[i] = 0;
  327.  
  328.                     av[ac++] = &string[from];
  329.                 }
  330.  
  331.                 from = i + 1;
  332.                 break;
  333.         }
  334.     }
  335.  
  336.     if(from < len - 1)
  337.         av[ac++] = &string[from];
  338.  
  339.     av[ac] = NULL;
  340.  
  341.         return (ac);
  342. #else
  343.         int ac = 0;
  344.         char *p;
  345.  
  346.         p = strchr(string,';');
  347.         if (p) *p = '\0';
  348.  
  349.         strupr(string);
  350.  
  351.         av[ac] = strtok(string," \t\r\n\032");
  352.  
  353.         while (av[ac]) {
  354.               if (++ac > MAXARGS) {
  355.                  message(6,"!Too many arguments!");
  356.                  endprog(2);
  357.               }
  358.               av[ac]=strtok(NULL," \t\r\n\032");
  359.         }
  360.         return (ac);
  361. #endif
  362. }/*parse()*/
  363.  
  364.  
  365. void splitpath(char *filepath,char *path,char *file)
  366. {
  367. #ifdef AMIGA
  368.     STRPTR path_name,file_name;
  369.     LONG len;
  370.  
  371.     path_name = PathPart(filepath);
  372.     file_name = FilePart(filepath);
  373.  
  374.     strcpy(file,file_name);
  375.  
  376.     len = path_name - filepath;
  377.  
  378.     memcpy(path,filepath,len);
  379.  
  380.     path[len] = 0;
  381. #else
  382.         char *p,*q;
  383.  
  384.         for (p=filepath;*p;p++) ;
  385.         while (p!=filepath && *p!=':' && *p!='\\' && *p!='/') --p;
  386.         if (*p==':' || *p=='\\' || *p=='/') ++p;        /* begin     */
  387.         q=filepath;
  388.         while (q!=p) *path++=*q++;                      /* copy path */
  389.         *path='\0';
  390.         strcpy(file,p);
  391. #endif    /* AMIGA */
  392. }/*splitpath()*/
  393.  
  394.  
  395. void mergepath(char *filepath,char *path,char *file)
  396. {
  397. #ifdef AMIGA
  398.     strcpy(filepath,path);
  399.     AddPart(filepath,file,256);
  400. #else
  401.         strcpy(filepath,path);
  402.         strcat(filepath,file);
  403. #endif    /* AMIGA */
  404. }/*mergepath()*/
  405.  
  406.  
  407. int fexist (char *filename)
  408. {
  409. #ifdef AMIGA
  410.     BPTR file_lock;
  411.  
  412.     if(file_lock = Lock(filename,SHARED_LOCK))
  413.         UnLock(file_lock);
  414.     else
  415.     {
  416.             /* Special case, the file in question may
  417.              * still be open for writing.
  418.              */
  419.  
  420.         if(IoErr() != ERROR_OBJECT_IN_USE)
  421.             return(0);
  422.     }
  423.  
  424.     return(1);
  425. #else
  426.         struct stat f;
  427.  
  428.         return ((stat(filename,&f) != -1) ? 1 : 0);
  429. #endif    /* AMIGA */
  430. }/*fexist()*/
  431.  
  432.  
  433. int get_key (void)
  434. {
  435. #ifdef AMIGA
  436.         return(ConGetKey());
  437. #else
  438. #if WIN_AGL
  439.         if (didsome)
  440.            return (win_keygetc());
  441.         else
  442. #endif
  443.              {
  444.            register int c = getch();
  445.  
  446.            return (c ? c : getch() | 0x100);
  447.         }
  448. #endif    /* AMIGA */
  449. }/*get_key()*/
  450.  
  451.  
  452. void any_key (void)
  453. {
  454.         fprintf(stderr,"Press any key to continue");
  455.         get_key();
  456.         fprintf(stderr,"\r                          \r");
  457. }/*any_key()*/
  458.  
  459.  
  460. int get_str (char *prompt, char *s, int maxlen)
  461. {
  462.         int i = (int) strlen(s),c;
  463.  
  464.         cprint("\r%s: %s",prompt,s);
  465.         for (;;) {
  466. #ifdef AMIGA
  467.             sys_idle();
  468.             if(!ConScanKey()) continue;
  469. #endif    /* AMIGA */
  470.             switch (c = get_key()) {
  471.                    case 13:
  472.                         s[i] = '\0';
  473.                         cprint("\n");
  474.                         return (i);
  475.  
  476.                    case 27:
  477.                         if (i) {
  478.                            do cprint("\b \b");
  479.                            while (--i);
  480.                         }
  481.                         s[0] = '\0';
  482.                         cprint("<aborted>\n");
  483.                         return (-1);
  484.  
  485.                    case 8:
  486.                    case 127:
  487.                         if (i) {
  488.                            --i;
  489.                            cprint("\b \b");
  490.                         }
  491.                         break;
  492.  
  493.                    default:
  494. #ifdef AMIGA
  495.                         if (i == maxlen || !((c >= 32 || c <= 126) && (c >= 160 || c <= 255))) {
  496. #else
  497.                         if (i == maxlen || c < 32 || c > 126) {
  498. #endif    /* AMIGA */
  499. #if WIN_AGL
  500.                            (void) win_bell();
  501. #else
  502. #ifdef AMIGA
  503.                            ConPrintf(LocalRequest,"\a");
  504. #else
  505.                            putc(7,stderr);
  506. #endif
  507. #endif
  508.                         }
  509.                         else {
  510.                            cprint("%c",c);
  511.                            s[i++] = c;
  512.                         }
  513.                         break;
  514.             }/*switch*/
  515.         }/*for*/
  516. }/*get_str()*/
  517.  
  518.  
  519. void resultlog (boolean xmit, char *fname, long bytes, long xfertime)
  520. {          /* Omen's DSZ compatible logfile - for RBBS-PC XFER-?.DEF reports */
  521.         FILE *fp;
  522.  
  523.         if (opuslog) {
  524.            if ((fp = sfopen(opuslog,"at",DENY_WRITE)) != NULL) {
  525.               if (fname) {
  526.                  fprintf(fp, "%s %s%s %ld", xmit ? "Sent" : "Got",
  527.                              xmit ? "" : download, fname, bytes);
  528.                  if (mailer)
  529.                     fprintf(fp," %ld",xfertime);
  530.                  fprintf(fp,"\n");
  531.               }
  532.               fclose(fp);
  533.            }
  534.            else
  535.               message(3,"-Couldn't append opus log-file %s",opuslog);
  536.         }
  537.  
  538.         if (result) {
  539.            if ((fp = sfopen(result,"at",DENY_WRITE)) != NULL) {
  540.               if (fname) {
  541.                  fprintf(fp, "%c %6ld %5u bps %4ld cps 0 errors     0 1024 %s -1\n",
  542.                              xmit ? 'H' : 'R',
  543.                              bytes, cur_speed,
  544.                              xfertime ? (bytes / xfertime) : 9999L,
  545.                              fname);
  546.               }
  547.               fclose(fp);
  548.            }
  549.            else
  550.               message(3,"-Couldn't append result-file %s",result);
  551.         }
  552. }/*resultlog()*/
  553.  
  554.  
  555. static char *mon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  556.                          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  557.  
  558. char *h_revdate (long revstamp)
  559. {
  560.         static char  buf[12];
  561.         struct tm   *t;
  562.  
  563.         t = localtime(&revstamp);
  564.         sprintf(buf, "%02d %s %d",
  565.                      t->tm_mday, mon[t->tm_mon], t->tm_year + 1900);
  566.  
  567.         return (buf);
  568. }/*h_revdate()*/
  569.  
  570.  
  571. void message (int level, char *fmt,...)
  572. {
  573.         char       buf[255];
  574.         long       tim;
  575.         struct tm *t;
  576.         va_list    arg_ptr;
  577.  
  578.         tim = time(NULL);
  579.         t = localtime(&tim);
  580.  
  581.         va_start(arg_ptr,fmt);
  582.         sprintf(buf, "%c %02d %03s %02d:%02d:%02d %-4s ",
  583.                      *fmt, t->tm_mday, mon[t->tm_mon],
  584.                      t->tm_hour, t->tm_min, t->tm_sec, LOGID);
  585.         vsprintf(&buf[23], &fmt[1], arg_ptr);
  586.         va_end(arg_ptr);
  587.  
  588.         if (level >= loglevel && logfp)
  589.            fprintf(logfp, "%s\n", buf);
  590.  
  591. #if WIN_AGL
  592.         if (!file_win)
  593.            cprint("\r%s\n",buf);
  594.         else {
  595.            if (!log_first)
  596.               log_first = true;
  597.            else
  598.               win_putc(log_win,'\n');
  599.            win_puts(log_win,buf);
  600.         }
  601. #else
  602. #ifdef AMIGA
  603.         if (!LogRequest)
  604.            cprint("%s\n",buf);
  605.         else
  606.            ConPrintf(LogRequest,"%s\n",buf);
  607. #else
  608.         if (!file_x)
  609.            cprint("\r%s\n",buf);
  610.         else {
  611.            local_x = wherex();
  612.            local_y = wherey();
  613.            window(1,2,80,6);
  614.            if (log_y) {
  615.               gotoxy(1,log_y);
  616.               putch('\n');
  617.            }
  618.            cputs(buf);
  619.            log_y = wherey();
  620.            window(1,19,80,25);
  621.            gotoxy(local_x,local_y);
  622.         }
  623. #endif
  624. #endif
  625. }/*message()*/
  626.  
  627.  
  628. void cprint (char *fmt, ...)
  629. {
  630.         char    buf[255];
  631.         va_list arg_ptr;
  632.  
  633.         va_start(arg_ptr,fmt);
  634.         vsprintf(buf, fmt, arg_ptr);
  635.         va_end(arg_ptr);
  636.  
  637. #if WIN_AGL
  638.         if (didsome)
  639.            win_puts(0,buf);
  640.         else
  641. #else
  642. #ifdef AMIGA
  643.         if (LocalRequest)
  644.            ConPrintf(LocalRequest,buf);
  645.         else
  646. #endif
  647. #endif
  648.            fputs(buf,stdout);
  649. }/*cprint()*/
  650.  
  651.  
  652. void hydra_gotoxy (int x, int y)
  653. {
  654. #if WIN_AGL
  655.         win_setpos(file_win,x,y);
  656. #else
  657. #ifdef AMIGA
  658.         ConMove(FileRequest,x,y);
  659. #else
  660.         file_x = x;
  661.         file_y = y;
  662. #endif
  663. #endif
  664. }/*hydra_gotoxy()*/
  665.  
  666.  
  667. void hydra_printf (char *fmt, ...)
  668. {
  669.         char    buf[255];
  670.         va_list arg_ptr;
  671.  
  672.         va_start(arg_ptr,fmt);
  673.         vsprintf(buf, fmt, arg_ptr);
  674.         va_end(arg_ptr);
  675.  
  676. #if WIN_AGL
  677.         win_puts(file_win,buf);
  678. #else
  679. #ifdef AMIGA
  680.         ConPrintf(FileRequest,buf);
  681. #else
  682.         local_x = wherex();
  683.         local_y = wherey();
  684.         window(1,8,80,9);
  685.  
  686.         gotoxy(file_x,file_y);
  687.         cputs(buf);
  688.  
  689.         file_x = wherex();
  690.         file_y = wherey();
  691.         window(1,19,80,25);
  692.         gotoxy(local_x,local_y);
  693. #endif
  694. #endif
  695. }/*hydra_printf()*/
  696.  
  697.  
  698. void hydra_clreol (void)
  699. {
  700. #if WIN_AGL
  701.         win_clreol(file_win);
  702. #else
  703. #ifdef AMIGA
  704.         ConPrintf(FileRequest,"\33[K");
  705. #else
  706.         local_x = wherex();
  707.         local_y = wherey();
  708.         window(1,8,80,9);
  709.  
  710.         gotoxy(file_x,file_y);
  711.         clreol();
  712.  
  713.         file_x = wherex();
  714.         file_y = wherey();
  715.         window(1,19,80,25);
  716.         gotoxy(local_x,local_y);
  717. #endif
  718. #endif
  719. }/*hydra_clreol()*/
  720.  
  721. /* end of misc.c */
  722.